/**
 * 
 */
package compilador.analizadorSintactico.categoriasSintacticas;

import java.util.ArrayList;

import javax.swing.tree.DefaultMutableTreeNode;

import compilador.analizadorSemantico.tablaSimbolos.TablaSimboloSemantico;
import compilador.analizadores.AnalizadorSemantico;
import compilador.interfaces.Asignable;

/**
 * @author Nolberto Castellanos Rodriguez
 * @author Yurani Alejandra Salamanca Lotero
 *
 * Clase que representa una Expresion Aritmetica
 */
public class ExpresionAritmetica implements Asignable{
	
//	-------------------------------------------------------------------------------------------------
//	ATRIBUTOS
//	-------------------------------------------------------------------------------------------------
	
	
	/**
	 *  Atributo que contiene la lista de los terminos
	 */
	private ArrayList<Termino> terminos;
	
	/**
	 *  Atributo que contiene la lista de los simbolos aritmeticos
	 */
	private ArrayList<SimbolosAritmeticos> simbolosAritmeticos;
	
	
//	-------------------------------------------------------------------------------------------------
//	CONSTRUCTOR
//	-------------------------------------------------------------------------------------------------
	

	/**
	 * Constructor que permite crear una expresion aritmetica
	 * @param terminos. Terminos que hay en la expresion
	 * @param simbolosAritmeticos. Simbolo aritmetico de la expresion aritmetica
	 */
	public ExpresionAritmetica(ArrayList<Termino> terminos,
			ArrayList<SimbolosAritmeticos> simbolosAritmeticos) {
		super();
		this.terminos = terminos;
		this.simbolosAritmeticos = simbolosAritmeticos;
	}

//	-------------------------------------------------------------------------------------------------
//	METODOS
//	-------------------------------------------------------------------------------------------------	

	/**
	 * @param ts
	 * @param errores
	 * @param claseActual
	 * @param metodoActual
	 */
	public void analizarSemantica(TablaSimboloSemantico ts,	ArrayList<SimboloError> errores, String claseActual, String metodoActual) {
		if(terminos != null && simbolosAritmeticos != null){
			if(terminos.size() == simbolosAritmeticos.size()+1){
				String tipo1 = terminos.get(0).determinarTipo();
				for (int i = 1; i <terminos.size(); i++) {
					String tipo2 = terminos.get(i).determinarTipo();
					if(!AnalizadorSemantico.verificarCompatibilidad(tipo1, tipo2)){
						errores.add(new SimboloError("Expresion incorrecta", terminos.get(i).getFactores().get(0).getFactor().getFila(), terminos.get(i).getFactores().get(0).getFactor().getColumna()));
						break;
					}
					
					tipo1 = AnalizadorSemantico.calcularTipo(tipo1, tipo2);
				}
			}
		}
	}
	
	
	/**
	 * Metodo que permite agregar hojas al nodo de la clase
	 * @return el nodo de la clase con sus hojas
	 */
	public  DefaultMutableTreeNode getArbolVisual(){
		DefaultMutableTreeNode miRaiz =  new  DefaultMutableTreeNode("Expresion Aritmetica");
		
		for (Termino termino : terminos) {
			miRaiz.add(termino.getArbolVisual());
		}
		
		for (SimbolosAritmeticos simboloAritmetico : simbolosAritmeticos) {
			miRaiz.add(simboloAritmetico.getArbolVisual());
		}
		
		return miRaiz;
	}
	
	public String determinarTipoDato(TablaSimboloSemantico ts, String claseActual, String metodoActual){
		
		String tipo = "";
		
		if(terminos == null)
			return tipo;

		tipo =  terminos.get(0).determinarTipo();
		
		for (int i = 1; i < terminos.size(); i++) {
			tipo = AnalizadorSemantico.calcularTipo(tipo, terminos.get(i).determinarTipo());
		}
		
		return tipo;
	}

	/**
	 * @return
	 */
	public String getJavaCode() {
		String retornable = "";
		
		if(terminos != null && terminos.size() > 0)
			retornable += terminos.get(0).getJavaCode();
		
		if(simbolosAritmeticos != null)
			for (int i = 1; i < terminos.size(); i++) {
				
				if(i<simbolosAritmeticos.size()-1)
					retornable+=simbolosAritmeticos.get(i-1);
				
				retornable += terminos.get(i).getJavaCode();
			}
		
		return retornable;
	}
	
//	-------------------------------------------------------------------------------------------------
//	Getters And Setters
//	-------------------------------------------------------------------------------------------------
	
	/**
	 * Metodo que nos retorna el valor de terminos
	 * @return  terminos. Valor retornado
	 */
	public ArrayList<Termino> getTerminos() {
		return terminos;
	}


	/**
	 * Metodo que permite asignar el valor de terminos
	 * @param terminos. Valor a asignar terminos
	 */
	public void setTerminos(ArrayList<Termino> terminos) {
		this.terminos = terminos;
	}


	/**
	 * Metodo que nos retorna el valor de simbolosAritmeticos
	 * @return  simbolosAritmeticos. Valor retornado
	 */
	public ArrayList<SimbolosAritmeticos> getSimbolosAritmeticos() {
		return simbolosAritmeticos;
	}


	/**
	 * Metodo que permite asignar el valor de simbolosAritmeticos
	 * @param simbolosAritmeticos. Valor a asignar simbolosAritmeticos
	 */
	public void setSimbolosAritmeticos(
			ArrayList<SimbolosAritmeticos> simbolosAritmeticos) {
		this.simbolosAritmeticos = simbolosAritmeticos;
	}

}
